home *** CD-ROM | disk | FTP | other *** search
- /*
- * process-uucp.c -- Make mmdf tables from uucp project derived information.
- *
- * USAGE: process-uucp [ -d domain ... ] [ -r relay-host ]
- * [ -c host ... ] file ...
- *
- * -d domain generate a domain table for the domain.
- * The file name is "wrkdmn.uucp-dom.ain", and
- * the entries are like:
- *
- * dom: dom.ain
- *
- * -r relay-host have the entries in the domain file be
- * routed through "relay-host". i.e.
- *
- * dom: dom.ain, relay-host
- *
- * -c host This causes the wrkchn.uucp-uucp file to be split into
- * multiple files. If a path has its' first component
- * as the named host, then the entry will be put
- * into a seperate file named "wrkchn.uucp-host".
- *
- * The input file is the output of pathalias. The format is:
- *
- * {host,domain} a!b!c!...%s...
- *
- * From this we make both domain tables and channel tables.
- *
- * There are a couple of files which are automatically created:
- *
- * wrkchn.uucp-uucp This contains domain:path entries for any paths
- * which did not match hosts given in the -c list.
- * wrkdmn.uucp-top This domains dom:dom.ain entries for domains
- * which did not match domains given in -d's.
- *
- * A word about the file naming scheme. The general format of file
- * names which I use on tables is "<type>.<source>-<subtype>".
- * "<type>" is something like domain, chan, or alias. "<source>"
- * is some identifier saying where the information came from, like
- * uucp or bitnet. "<subtype>" is something like domain for domain
- * tables, channel name for channel tables, or some other sort of
- * identifier depending on what the table is for. (For instance,
- * I also have alias-global, alias-forward, and alias-local tables).
- *
- * Suggested use is something like:
- *
- * process-uucp -d uucp -d edu -d arpa pathalias-output-file
- *
- * AUTHOR:
- *
- * David Herron, University of Kentucky Mathematical Sciences
- * Mon Nov 16 17:39:18 EST 1987
- */
-
- #include <stdio.h>
- #include <ctype.h>
-
- struct namelist {
- char *name;
- char *fname;
- /* FILE *ofile; */
- };
-
- /* File name prefixes */
- #define WRK_CHAN "wrkchn.uucp"
- #define WRK_DMN "wrkdmn.uucp"
-
- void process();
- char buf[BUFSIZ];
-
-
- void addfile();
- char *files[BUFSIZ];
- int numfiles = 0;
-
-
- void addomain();
- struct namelist domains[BUFSIZ];
- int numdomains = 0;
-
-
- void addhost();
- struct namelist hosts[BUFSIZ];
- int numhosts = 0;
-
-
- char *lowerify();
- char *RelayHost = (char *)0;
-
- extern char *malloc();
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- int i;
-
- if (argc <= 1) {
- fprintf(stderr, "Usage: %s file ...\n", argv[0]);
- exit(1);
- }
- sprintf(buf, "%s-uucp", WRK_CHAN);
- close(creat(buf, 0644));
- for (i=1; i < argc; i++) {
- if (argv[i][0] == '-') {
- switch(argv[i][1]) {
- case 'd':
- i++;
- printf("addomain(%s);\n", argv[i]);
- addomain(argv[i]);
- break;
- case 'c':
- i++;
- printf("addhost(%s);\n", argv[i]);
- addhost(argv[i]);
- break;
- case 'r':
- i++;
- RelayHost = lowerify(argv[i]);
- printf("relay-host: %s\n", RelayHost);
- break;
- default:
- break;
- }
- }
- else {
- addfile(argv[i]);
- }
- }
- for (i=0; i<numfiles; i++) {
- /* printf("process(%s);\n", files[i]); */
- process(files[i]);
- }
- exit(0);
- }
-
- void
- addomain(s)
- char *s;
- {
- int slen;
-
- domains[numdomains].name = s;
- slen = strlen(WRK_DMN) + 1 + strlen(s) + 1;
- domains[numdomains].fname = malloc(slen);
- sprintf(domains[numdomains].fname, "%s-%s", WRK_DMN, s);
- numdomains++;
- }
-
- void
- addhost(s)
- char *s;
- {
- int slen;
-
- hosts[numhosts].name = s;
- slen = strlen(WRK_DMN) + 1 + strlen(s) + 1;
- hosts[numhosts].fname = malloc(slen);
- sprintf(hosts[numhosts].fname, "%s-%s", WRK_CHAN, s);
- numhosts++;
- }
-
- void
- addfile(s)
- char *s;
- {
- files[numfiles++] = s;
- }
-
- char *
- lowerify(s)
- char *s;
- {
- register char *sp = s;
-
- while (*sp != '\0') {
- if (isupper(*sp))
- *sp = tolower(*sp);
- sp++;
- }
- return(s);
- }
-
- /*
- * indomain(name, domain) -- Test to see if the given name is
- * within a domain ... we do this as a sort of reverse-strcmp().
- *
- * The return value is NULL if it is not, and a pointer within the
- * tested name if it is.
- */
- char *
- indomain(name, domain)
- char *name, *domain;
- {
- register char *namp, *domp;
-
- namp = name; domp = domain;
- if (!namp || !domp)
- return(NULL);
- /* printf("indomain(%s, %s); -- ", name, domain); */
- /* Find the end of the strings */
- namp = &(name[strlen(name)-1]);
- domp = &(domain[strlen(domain)-1]);
- /* printf("start at namp=<%s> domp=<%s> -- ", namp, domp); */
- for (; namp>=name && domp>=domain; namp--, domp--)
- if (namp[0] != domp[0])
- break;
- namp++; domp++;
- /* printf("match at namp=<%s> domp=<%s>\n", namp, domp); */
- if (
- (namp>name && domp==domain && namp[-1]=='.')
- || namp == name
- )
- return(namp);
- else
- return(NULL);
- }
-
- /* These have to be here because the compiler chokes if they're
- * inside process().
- */
- char pathbuf[BUFSIZ], dmnbuf[BUFSIZ], bf2[BUFSIZ];
-
- /*
- * process(file) -- Process the file making all the tables which
- * which we were told to make on the command line.
- *
- * A note about the algorithm. If you read the code below you will
- * notice that I am constantly open()ing and close()ing files to
- * append records to the end of the files. This is because, in
- * theory at least, someone could have 50 domain files that they
- * generate from this program.
- *
- * Maybe in practice one will never have more than 10 (to pick a number
- * out of the air). If you really want to "fix" this, be my guest. It
- * should be a fairly trivial re-write. The "fix" I have in mind is to
- * change "domains[]" into an array of structures remembering the domain
- * name, the file name for the domain, and the FILE * pointing to that
- * file. Then there are a few places below where one looks up the
- * file name, fopen()s the file in "a" mode, write the record, and close
- * the file. One would need to change those places to merely write the
- * record after looking up the FILE * in the struct namelist.
- *
- * NOTE NOTE NOTE ... The procedure as it is opens files in append mode
- * and there's no automatic truncation of any files. You will have to
- * do this by hand. (Well, engrave it in your shell script which processes
- * the pathalias output).
- */
- void
- process(file)
- char *file;
- {
- register char *sp, *sp2;
- register int i;
- FILE *ifile, *cfile, *tcfile, *dfile, *topfile;
- int hlen;
- char *index(), *strcpy(), *strcat();
-
- ifile = fopen(file, "r");
- if (ifile == NULL) {
- /* printf("Open of %s failed with errno=%d\n", file, errno); */
- perror(file);
- return;
- }
- sprintf(buf, "%s-uucp", WRK_CHAN);
- cfile = fopen(buf, "a");
- if (cfile == NULL) {
- /* printf("Open of %s failed with errno=%d\n", buf, errno); */
- perror(buf);
- fclose(ifile);
- return;
- }
- sprintf(buf, "%s-top", WRK_DMN);
- topfile = fopen(buf, "a");
- if (topfile == NULL) {
- /* printf("Open of %s failed with errno=%d\n", buf, errno); */
- perror(buf);
- fclose(ifile);
- fclose(cfile);
- return;
- }
- while (fgets(buf, BUFSIZ, ifile) != NULL) {
- if ((sp = index(buf, '\n')) != NULL)
- *sp = '\0';
- /* copy the domain part */
- for (sp=buf, sp2=dmnbuf;
- *sp!='\0' && *sp!=' ' && *sp!='\t';
- sp++, sp2++)
- *sp2 = *sp;
- *sp2 = '\0';
- /* Then the path part */
- if (*sp != '\0') {
- while (*sp==' ' || *sp=='\t')
- sp++;
- for (sp2=pathbuf;
- *sp!='\0' && *sp!=' ' && *sp!='\t';
- sp++, sp2++)
- *sp2 = *sp;
- *sp2 = '\0';
- }
- if (pathbuf[0] == '\0')
- strcpy(pathbuf, "NO-PATH-GIVEN!%s");
- /* printf("before = %s\n", dmnbuf); */
- (void) lowerify(dmnbuf);
- /* printf("after = %s\n", dmnbuf); */
- if ((sp = index(dmnbuf, '.')) == NULL)
- strcat(dmnbuf, ".uucp");
- if (dmnbuf[0] == '.')
- for (sp = dmnbuf; *sp != '\0'; sp++)
- *sp = *(sp+1);
- /*
- * If the given domain name is within one of those for which
- * we have a domain table, output it into the domain table
- * and into the channel table.
- */
- for (i=0; i<numdomains; i++) {
- if ((sp2=indomain(dmnbuf, domains[i].name)) != NULL) {
- if (sp2 > dmnbuf) {
- dfile = fopen(domains[i].fname, "a");
- /* write out first part of dom.ain */
- for (sp=dmnbuf; sp < (sp2-1); sp++)
- fputc(*sp, dfile);
- if (RelayHost)
- fprintf(dfile, ":\t%s, %s\n",
- dmnbuf, RelayHost);
- else
- fprintf(dfile, ":\t%s\n", dmnbuf);
- fclose(dfile);
- break;
- }
- else {
- /*
- * This case is for when the name we're
- * testing fully matches the domain name
- * for one of the tables. We aren't
- * supposed to make an entry for him
- * in this table, but in the table for
- * the parent domain. But we don't
- * know here whether we are keeping
- * a table for that domain ... HOWEVER,
- * if we keep looping through the rest of
- * the table names we will eventually
- * find out.
- */
- continue;
- }
- }
- }
- /*
- * This case is for when we've run through the entire list
- * of domains for which we have tables and the name we
- * have does not fit with any of those. So, we insert
- * it into the top-level table.
- */
- if (i == numdomains) {
- if (RelayHost)
- fprintf(topfile, "%s:\t%s, %s\n",
- dmnbuf, dmnbuf, RelayHost);
- else
- fprintf(topfile, "%s:\t%s\n", dmnbuf, dmnbuf);
- }
- /*
- * This section handles making entries in the channel table.
- */
- if (numhosts > 0) {
- for (i=0; i<numhosts; i++) {
- hlen = strlen(hosts[i].name);
- /* This shortcuts if we already know that
- * the names CANNOT match. i.e. if the next
- * character is not '!', then the lengths
- * of the two names are not the same.
- */
- if (pathbuf[hlen] != '!')
- continue;
- if (strncmp(pathbuf, hosts[i].name, hlen) != 0)
- continue;
- tcfile = fopen(hosts[i].fname, "a");
- fprintf(tcfile, "%s:\t%s\n", dmnbuf, pathbuf);
- fclose(tcfile);
- break;
- }
- /* If we make it all the way through the list, then
- * we didn't write out the record to a file. Put
- * the record out into the default file.
- */
- if (i == numhosts)
- fprintf(cfile, "%s:\t%s\n", dmnbuf, pathbuf);
- }
- else
- fprintf(cfile, "%s:\t%s\n", dmnbuf, pathbuf);
- }
- /* printf("done with %s\n", file); */
- fclose(cfile);
- fclose(ifile);
- fclose(topfile);
- }
-